package de.hwrberlin.remo.diagram.custom.actions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

import de.hwrberlin.expertsystem.util.ModelEditingHelper;
import de.hwrberlin.remo.algorithm.InferenzAlgorithm;
import de.hwrberlin.remo.algorithm.InferenzAlgorithmRegistry;
import de.hwrberlin.remo.algorithm.InferenzAlgorithmXP;
import de.hwrberlin.remo.algorithm.UserInterface;
import de.hwrberlin.remo.algorithm.steps.AlgorithmStep;
import de.hwrberlin.remo.algorithm.util.AlgorithmDebugger;
import de.hwrberlin.remo.algorithm.util.AlgorithmStepSaver;
import de.hwrberlin.remo.diagram.custom.dialogs.AlgorithmDebugDialog;
import de.hwrberlin.remo.diagram.custom.dialogs.AlgorithmSelectionDialog;
import de.hwrberlin.remo.diagram.custom.dialogs.ExecutionMode;
import de.hwrberlin.remo.diagram.custom.util.DiagramEditorUserInterface;

public class StartAlgorithmAction extends AbstractRemoDiagramAction {

	@Override
	public void run(IAction action) {
		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
		AlgorithmSelectionDialog dialog = new AlgorithmSelectionDialog(shell,
				InferenzAlgorithmRegistry.getRegisteredAlgorithms());
		
		if(dialog.open() == Dialog.OK) { 
			ModelEditingHelper editingHelper = new ModelEditingHelper(expertSystemEditor.getEditingDomain());
			UserInterface visualisationHelper = new DiagramEditorUserInterface(expertSystemEditor);
			
			InferenzAlgorithmXP selectedAlgorithmXP = dialog.getAlgorithm();
			InferenzAlgorithm algorithm = selectedAlgorithmXP.getAlgorithm();
			algorithm.setEditingHelper(editingHelper);
			algorithm.setUserInterface(visualisationHelper);
			
			editingHelper.resetRules(knowledgeBase);
			visualisationHelper.unhighlightAllElement(knowledgeBase.getOwnedElements());

			if(dialog.getExecutionMode() == ExecutionMode.DEBUG) {
				// Get algorithm steps
				AlgorithmStepSaver saver = new AlgorithmStepSaver();
				algorithm.registerListener(saver);
				
				algorithm.start(knowledgeBase);

				List<AlgorithmStep> steps = saver.getSteps();
				if(steps == null || steps.isEmpty()) {
					return;
				}
				
				// Reverse algorithm step list 
				List<AlgorithmStep> revertAll = new ArrayList<AlgorithmStep>(steps);
				Collections.reverse(revertAll);
				
				// Revert steps 
				for(AlgorithmStep step : revertAll) {
					step.revert();
				}
				
				AlgorithmDebugger debugger = new AlgorithmDebugger(saver.getSteps());
				
				// Show debug dialog
				AlgorithmDebugDialog debuggerDialog = new AlgorithmDebugDialog(shell, 
						debugger, selectedAlgorithmXP.getName());
				debuggerDialog.open(); 
				
			} else if(dialog.getExecutionMode() == ExecutionMode.NORMAL) {
				
				algorithm.start(knowledgeBase);
				
//				//algorithm.initialize(knowledgeBase);
//				AlgorithmExecutionJob executionJob = new AlgorithmExecutionJob(
//						selectedAlgorithmXP.getName(),
//						selectedAlgorithmXP.getAlgorithm(),
//						knowledgeBase);
//				
//				try {
//					new ProgressMonitorDialog(shell).run(false, true, executionJob);
//				} catch (InvocationTargetException e) {
//					e.printStackTrace();
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
			}
			
			expertSystemEditor.doSave(new NullProgressMonitor());
		}
	}

	@Override
	public void selectionChanged(IAction action, ISelection selection) {
		// Do nothing
	}
}